home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / lib / xvaredit.pro < prev    next >
Text File  |  1997-07-08  |  13KB  |  369 lines

  1. ; $Id: xvaredit.pro,v 1.6 1997/03/10 22:23:39 lubos Exp $
  2. ;
  3. ; Copyright (c) 1991-1997, Research Systems, Inc.  All rights reserved.
  4. ;    Unauthorized reproduction prohibited.
  5. ;+
  6. ; NAME:
  7. ;    XVAREDIT
  8. ; PURPOSE:
  9. ;    This routine provides an editor for any IDL variable.
  10. ; CATEGORY:
  11. ;    Widgets
  12. ; CALLING SEQUENCE:
  13. ;    XVAREDIT, VAR
  14. ; INPUTS:
  15. ;    VAR = The variable that is to be edited.
  16. ; KEYWORD PARAMETERS:
  17. ;    NAME = The NAME of the variable.  This keyword is overwritten with the
  18. ;        structure name if the variable is a structure.
  19. ;    GROUP = The widget ID of the widget that calls XVarEdit.  When this
  20. ;        ID is specified, a death of the caller results in a death of
  21. ;        XVarEdit.
  22. ;    X_SCROLL_SIZE = The X_SCROLL_SIZE keyword allows you to set
  23. ;        the width of the scrolling viewport in columns.
  24. ;        Default is 4.
  25. ;    Y_SCROLL_SIZE = The Y_SCROLL_SIZE keyword allows you to set
  26. ;        the height of the scrolling viewport in rows.
  27. ;        Default is 4.
  28. ; OUTPUTS:
  29. ;    VAR= The variable that has been edited, or the original when the user
  30. ;        selects the "Cancel" button in the editor.
  31. ; COMMON BLOCKS:
  32. ;    None.
  33. ; SIDE EFFECTS:
  34. ;    Initiates the XManager if it is not already running.
  35. ; RESTRICTIONS:
  36. ;    None known.
  37. ; PROCEDURE:
  38. ;    Create and register the widget and then exit.
  39. ;    If the user selects "accept", the values in the editor are written
  40. ;    to the variable passed in, otherwise, they are ignored.
  41. ; MODIFICATION HISTORY:
  42. ;    Written by: Steve Richards,    February, 1991
  43. ;    Modified: September 96, LP - rewritten with TABLE widget 
  44. ;-
  45.  
  46.  
  47. ;------------------------------------------------------------------------------
  48. ;    procedure XVarEdit_event
  49. ;------------------------------------------------------------------------------
  50. ; This procedure processes the events being sent by the XManager.
  51. ;------------------------------------------------------------------------------
  52. PRO XVarEdit_event, event
  53.  
  54. WIDGET_CONTROL, event.id, GET_UVALUE = whichevent
  55. IF N_ELEMENTS(whichevent) EQ 0 THEN RETURN
  56. IF whichevent NE "THEBUTTON" THEN RETURN
  57.  
  58. CASE event.value OF
  59.  
  60.     0: BEGIN                                            ;the user chose the 
  61.         WIDGET_CONTROL, event.top, /DESTROY        ;return the initial
  62.       END                        ;variable
  63.  
  64.     1: BEGIN                        ;the user chose accept
  65.         WIDGET_CONTROL, event.top, GET_UVALUE = pEval
  66.         IF (*pEval).usetable THEN BEGIN
  67.             edit_cell = WIDGET_INFO((*pEval).table, /TABLE_EDIT_CELL)
  68.             if edit_cell[0] EQ -1 AND edit_cell[1] EQ -1 then begin
  69.                 (*pEval).modified = 1
  70.                 WIDGET_CONTROL, (*pEval).table, GET_VALUE = var
  71.                 if (SIZE((*pEval).var))(0) EQ 0 then $
  72.                   (*pEval).var = var[0] $
  73.                 else $
  74.                   (*pEval).var = TEMPORARY(var)
  75.             endif else begin
  76.                 tmp = DIALOG_MESSAGE(['Please commit or cancel the edit',$
  77.                                       'before pressing Accept.'])
  78.                 RETURN
  79.             endelse
  80.         ENDIF ELSE BEGIN
  81.           i = 0
  82.           ;so go ahead and modify the variable
  83.           WIDGET_CONTROL, (*pEval).table, GET_VALUE = var
  84.        WHILE(i LT N_ELEMENTS((*pEval).entries))DO BEGIN
  85.               assign = '='
  86.               IF((*pEval).entries[i].type EQ 6)THEN assign = '=COMPLEX'
  87.               CATCH, errorStatus
  88.               IF errorStatus EQ 0 THEN $
  89.                 status = EXECUTE("(*pEval)." + (*pEval).entries[i].name + $
  90.                                  assign + var[i]) $
  91.               ELSE $
  92.                 tmp = DIALOG_MESSAGE([ 'XVarEdit conversion error:', $
  93.                                      '', !err_string ] , /error)
  94.               CATCH, /CANCEL
  95.               i = i + 1
  96.           ENDWHILE
  97.         ENDELSE
  98.     WIDGET_CONTROL, event.top, /DESTROY        ;once the variables 
  99.     END                        ;have been retrieved, 
  100.                             ;the widget heiarchy
  101.   ELSE:                         ;can be destroyed
  102.  
  103. ENDCASE
  104.  
  105. END ;============= end of XVarEdit event handling routine task =============
  106.  
  107.  
  108. ;------------------------------------------------------------------------------
  109. ;    procedure AddEditEntry
  110. ;------------------------------------------------------------------------------
  111. ; This procedure adds an entry to the list that contains the variables names
  112. ; and the widget id for the edit field corresponding to the variable name.
  113. ;------------------------------------------------------------------------------
  114.  
  115. PRO AddEditEntry, entries, nentries, thename, thetype, value
  116.  
  117. newelt = {entstr, name:thename, $            ;first create a record
  118.           value:value, $            ;and then 
  119.           type:thetype}                ;just create a list
  120. numents = N_ELEMENTS(entries)                ;with one more element
  121. IF(NOT(KEYWORD_SET(entries))) THEN BEGIN
  122.    entries = newelt                                     ;and replace the old 
  123.    nentries = 1
  124. ENDIF ELSE BEGIN                    ;one
  125.     IF (numents LE nentries) THEN BEGIN
  126.         newentries = REPLICATE(newelt, numents + 100)
  127.         newentries[0:numents - 1] = entries
  128.         nentries = numents + 1
  129.         newentries[numents] = newelt
  130.         entries = newentries
  131.     ENDIF ELSE BEGIN
  132.         entries[nentries] = newelt
  133.         nentries = nentries + 1
  134.     ENDELSE
  135. ENDELSE
  136. END ;============== end of XVarEdit event handling routine task ===============
  137.  
  138.  
  139. ;------------------------------------------------------------------------------
  140. ;    procedure XvarEditField
  141. ;------------------------------------------------------------------------------
  142. ;  This routine is used to create the widget or widgets needed for a given 
  143. ;  variable type.  It could call itself recursively if the variable was itself
  144. ;  a structure comprised of other IDL variables.
  145. ;------------------------------------------------------------------------------
  146.  
  147. FUNCTION XvarEditField, base, val, usetable, entries, nentries, NAME = NAME, $
  148.                         RECNAME = RECNAME, $
  149.                         X_SCROLL_SIZE = X_SCROLL_SIZE, $
  150.                         Y_SCROLL_SIZE = Y_SCROLL_SIZE
  151.  
  152. FORWARD_FUNCTION XvarEditField
  153.  
  154. typarr = ["Undefined", "Byte", "Integer", $        ;an array of names of 
  155.       "Longword Integer", "Floating Point", $    ;each type
  156.       "Double Precision Floating", $
  157.       "Complex Floating Point", $
  158.       "String", "Structure"]
  159.  
  160. varsize = size(val)                    ;determine the size and
  161. vardims = N_ELEMENTS(varsize) - 2            ;type of the variable
  162. type = varsize[vardims]
  163. numelements = varsize[vardims + 1]
  164.  
  165. usetable = 0
  166. IF (NOT(KEYWORD_SET(RECNAME)) AND $
  167.     (varsize[0] EQ 1 OR varsize[0] EQ 2)) THEN BEGIN
  168.     IF(type EQ 8) THEN BEGIN
  169.         FOR i = 0, N_TAGS(val) - 1 DO BEGIN
  170.             strsize = size(val.(i))
  171.             strdims = N_ELEMENTS(strsize) - 2
  172.             IF strsize[strdims] EQ 8 OR $
  173.               strsize[strdims + 1] NE varsize[vardims + 1] THEN $
  174.               Goto, Cplx_Struct
  175.         ENDFOR
  176.         usetable = 1
  177.     ENDIF ELSE BEGIN
  178.         usetable = 1
  179.     ENDELSE
  180. ENDIF
  181. Cplx_Struct:
  182. recurse = KEYWORD_SET(RECNAME)
  183.  
  184. IF (NOT recurse) THEN $
  185.   abase = WIDGET_BASE(base, /FRAME, /COLUMN, XPAD = 8, YPAD = 8)
  186.  
  187. IF(numelements GT 1) THEN BEGIN                ;if the variable is an
  188.   suffix = " Array("                    ;array, then say so and
  189.   FOR j = 1, varsize[0] DO BEGIN            ;show the array
  190.     suffix = suffix + strtrim(varsize[j], 2)        ;dimensions.
  191.     IF j NE varsize[0] THEN suffix = suffix + ", "
  192.   ENDFOR
  193.   suffix = suffix + ")"
  194. ENDIF ELSE suffix = ""
  195.  
  196.  
  197. IF(type EQ 8) THEN NAME = TAG_NAMES(val, /STRUCTURE)    ;if the variable is a 
  198.                             ;structure, use its 
  199.                             ;name
  200.  
  201. ;build up the name of variable with the type in parentheses
  202. IF(NOT recurse) THEN BEGIN
  203.     IF(KEYWORD_SET(NAME)) THEN $
  204.       lbl = WIDGET_LABEL(abase, $
  205.                          VALUE = NAME + " (" + typarr[type] + suffix + ")") $
  206.     ELSE lbl = WIDGET_LABEL(abase, $
  207.                             value = typarr[type] + suffix)
  208. ENDIF
  209.  
  210. IF(NOT(KEYWORD_SET(RECNAME))) THEN RECNAME = "var"    ;establish the name
  211.                             ;if not being called 
  212.                             ;recursively
  213.  
  214. IF(N_ELEMENTS(X_SCROLL_SIZE) EQ 0) THEN $
  215.   XSCROLL_SIZE = 4 ELSE XSCROLL_SIZE = X_SCROLL_SIZE
  216. IF(N_ELEMENTS(Y_SCROLL_SIZE) EQ 0) THEN $
  217.   YSCROLL_SIZE = 4 ELSE YSCROLL_SIZE = Y_SCROLL_SIZE
  218.  
  219. IF (usetable) THEN BEGIN
  220.     IF(type EQ 8) THEN BEGIN
  221.         table = WIDGET_TABLE(abase, value = val, $
  222.                              COLUMN_LABELS = TAG_NAMES(val), $
  223.                              /RESIZEABLE_COLUMNS, /EDIT, $
  224.                              X_SCROLL_SIZE = XSCROLL_SIZE, $
  225.                              Y_SCROLL_SIZE = YSCROLL_SIZE)
  226.     ENDIF ELSE BEGIN
  227.         table = WIDGET_TABLE(abase, value = val, $
  228.                              /RESIZEABLE_COLUMNS, /EDIT, $
  229.                              X_SCROLL_SIZE = XSCROLL_SIZE, $
  230.                              Y_SCROLL_SIZE = YSCROLL_SIZE)
  231.     ENDELSE
  232.     RETURN, table
  233. ENDIF
  234.  
  235. IF(varsize[0] GT 1) THEN BEGIN
  236.   moduli = LONARR(varsize[0]-1) + 1
  237.   FOR i = varsize[0], 2,-1 DO BEGIN
  238.     FOR j = 1,i-1 DO $
  239.       moduli[i - 2] = moduli[i - 2] * varsize[j]
  240.   ENDFOR
  241. ENDIF
  242.  
  243. FOR element = 0, numelements - 1 DO BEGIN        ;for each array element
  244.  
  245.   IF(numelements NE 1) THEN BEGIN            ;use array subscripting
  246.     indexname = "("                    ;if variable is an
  247.     indexname = indexname + $
  248.         strtrim(element mod varsize[1],2)
  249.     IF(varsize[0] GT 1) THEN BEGIN
  250.       indexarr = lonarr(varsize[0] - 1)
  251.       flatindex = element
  252.       FOR i = varsize[0] - 2, 0, -1 DO BEGIN
  253.     indexarr[i] = flatindex / moduli[i]
  254.     flatindex = flatindex mod moduli[i]
  255.       ENDFOR
  256.       FOR i = 0, varsize[0] - 2 DO $
  257.     indexname = indexname + ", " + $
  258.         strtrim(indexarr[i], 2)
  259.     ENDIF
  260.     indexname = indexname + ")"
  261.     thename = RECNAME + indexname
  262.   ENDIF ELSE BEGIN
  263.     thename = RECNAME
  264.   ENDELSE
  265.  
  266.   ;depending on the type, build a string variable with proper formatting
  267.   CASE type OF
  268.     0: thevalue = "Undefined Variable"            ;Undefined
  269.  
  270.     1: thevalue = string(val[element], $        ;Byte
  271.         FORMAT = '(I3)')
  272.  
  273.     7: thevalue = val[element]                ;String
  274.  
  275.     8: BEGIN                        ;Structure
  276.      tags = TAG_NAMES(val[element])
  277.      FOR i = 0, N_ELEMENTS(tags) - 1 DO BEGIN
  278.        error = EXECUTE("fieldvalue = val[element]." + tags[i])
  279.        fldsize = size(fieldvalue)
  280.        flddims = N_ELEMENTS(fldsize) - 2
  281.            id = XvarEditField(abase, fieldvalue, usetable, entries, nentries, $
  282.                               NAME = tags[i], $
  283.                               RECNAME = thename + "." + tags[i], $
  284.                               X_SCROLL_SIZE = XSCROLL_SIZE, $
  285.                               Y_SCROLL_SIZE = YSCROLL_SIZE)
  286.      ENDFOR
  287.     END
  288.  
  289.     ELSE: thevalue = strtrim(val[element], 2)
  290.   ENDCASE
  291.  
  292.   IF(type NE 8) THEN BEGIN      ;here the actual widget
  293.       AddEditEntry, entries, nentries, thename, type, thevalue
  294.   END
  295.  
  296. ENDFOR
  297.  
  298. table = 0
  299. IF (NOT recurse) THEN BEGIN
  300.     IF (N_ELEMENTS(entries.value) GT 1) THEN BEGIN
  301.         table = WIDGET_TABLE(abase, value = TRANSPOSE(entries.value), $
  302.                              ROW_LABELS = TRANSPOSE(entries.name), $
  303.                              COLUMN_LABELS = '', $
  304.                              /RESIZEABLE_COLUMNS, /EDIT, $
  305.                              COLUMN_WIDTHS=150, $
  306.                              Y_SCROLL_SIZE = YSCROLL_SIZE)
  307.     ENDIF ELSE BEGIN
  308.         table = WIDGET_TABLE(abase, value = [entries.value], $
  309.                              ROW_LABELS = [entries.name], $
  310.                              COLUMN_LABELS = '', $
  311.                              /RESIZEABLE_COLUMNS, /EDIT, $
  312.                              COLUMN_WIDTHS=150, $
  313.                              Y_SCROLL_SIZE = YSCROLL_SIZE)
  314.     ENDELSE
  315.     usetable = 1
  316. ENDIF
  317.  
  318.     return, table
  319. END ;============= end of XVarEdit event handling routine task =============
  320.  
  321.  
  322. ;------------------------------------------------------------------------------
  323. ;    procedure XVarEdit
  324. ;------------------------------------------------------------------------------
  325. ; this is the actual routine that is called.  It builds up the variable editing
  326. ; fields by calling other support routines and then registers the widget 
  327. ; heiarchy with the XManager.  Notice that the widget is registered as a MODAL
  328. ; widget so it will desensitize all other current widgets until it is done.
  329. ;------------------------------------------------------------------------------
  330. PRO XVarEdit, var, GROUP = GROUP, NAME = NAME, $
  331.               X_SCROLL_SIZE = X_SCROLL_SIZE, Y_SCROLL_SIZE = Y_SCROLL_SIZE
  332.  
  333. if(n_params() ne 1) THEN $
  334.   MESSAGE, "Must have one parameter"
  335.  
  336. XVarEditbase = WIDGET_BASE(TITLE = "XVarEdit", $    ;create the main base
  337.         /COLUMN)
  338.  
  339. menu = Cw_Bgroup(XVarEditbase, ['Cancel', 'Accept'], /ROW, UVALUE="THEBUTTON")
  340.  
  341. entries = 0
  342. nentries = 0
  343. table = XvarEditField(XVarEditbase, var, usetable, entries, nentries, $
  344.                       NAME = NAME, X_SCROLL_SIZE = X_SCROLL_SIZE, $
  345.                       Y_SCROLL_SIZE = Y_SCROLL_SIZE)
  346.  
  347. XVarEditStat = {var:var, $
  348.                 entries:entries, $
  349.                 modified:0, $
  350.                 table: table, $
  351.                 usetable: usetable}
  352. pXVarEditStat = PTR_NEW(XVarEditStat, /NO_COPY)
  353. WIDGET_CONTROL, XVarEditbase, SET_UVALUE=pXVarEditStat
  354.  
  355. WIDGET_CONTROL, XVarEditbase, /REALIZE
  356.  
  357. XManager, "XVarEdit", XVarEditbase, $            ;register the widgets
  358.         GROUP_LEADER = GROUP            ;and pass through the
  359.                             ;group leader if this
  360.                             ;routine is to be 
  361.                             ;called from some group
  362.                             ;leader.
  363. ; Get the return value
  364. IF ((*pXVarEditStat).modified) THEN var = (*pXVarEditStat).var
  365. PTR_FREE, pXVarEditStat
  366.  
  367. END ;================== end of XVarEdit main routine =======================
  368.  
  369.